package top.chendawei.main.web.controller;

import cn.hutool.json.JSONUtil;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.chendawei.aop.exceptions.CommonPartsExceptions;
import top.chendawei.main.facade.UserFacadeImpl;
import top.chendawei.system.beans.entity.SysRole;
import top.chendawei.system.beans.entity.SysUser;
import top.chendawei.system.beans.vo.param.UserAddParam;
import top.chendawei.system.beans.vo.param.UserParam;
import top.chendawei.system.enums.CommomOperator;
import top.chendawei.system.service.ICommonService;
import top.chendawei.system.service.impl.AuthServiceImpl;
import top.chendawei.system.util.annotation.SysLog;
import top.chendawei.system.web.controller.AbstractBaseController;
import top.chendawei.util.DateUtils;
import top.chendawei.util.EncryptTool;
import top.chendawei.util.JsonResult;
import top.chendawei.util.params.ResultMessage;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/sys/user")
@Api(tags = "系统用户")
public class SysUserController extends AbstractBaseController {
    @Autowired
    private ICommonService commonService;

    @Autowired
    private UserFacadeImpl userFacade;
    @Autowired
    private AuthServiceImpl authService;

    @SysLog(description = "查询用户列表")
    @GetMapping({"/page"})
    public ResultMessage page(UserParam param) {
        initPageParam(param);
        List<String> searchAttr = new ArrayList();
        List<Object> searchVal = new ArrayList();
        List<CommomOperator> searchOper = new ArrayList();
        if (StringUtils.isNoneBlank(param.getLoginNameLike())) {
            searchAttr.add("username");
            searchVal.add(param.getLoginNameLike());
            searchOper.add(CommomOperator.rightLike);
        }
        JsonResult<SysUser> json = this.commonService.search(searchAttr,
                searchVal, searchOper,
                SysUser.class, param.getCurrent().intValue(), param.getPageSize().intValue(), param.getOrderBy(), param.getOrderType());

        collectInfo(json.getRecords());
        return ResultMessage.success(json);
    }


    @PostMapping({"/queryUserInfo"})
    public ResultMessage<Object> queryUserInfo(HttpServletRequest request) {
        SysUser dbUser = userFacade.getUserFromToken(request);
        if (null == dbUser) {
            return ResultMessage.error("用户未登陆");
        }
        Map<String, Object> data = Maps.newHashMap();
        if (StringUtils.isNoneBlank(dbUser.getRoleIds())) {
            List<Long> ids = JSONUtil.toList(JSONUtil.parseArray(dbUser.getRoleIds()), Long.class);
            List<String> auths = authService.queryCheckedAuthIdList(ids).stream().map(x -> x + "").collect(Collectors.toList());
            data.put("permissions", auths);
        }
        data.put("user", dbUser);
        data.put("roleIds", dbUser.getRoleIdList());
        return ResultMessage.success(data);
    }

    private void collectInfo(List<SysUser> records) {
        Set<Long> roleIds = new HashSet<>();
        records.forEach(x -> {
            if (StringUtils.isNoneBlank(x.getRoleIds())) {
                List<Long> ids = JSONUtil.toList(JSONUtil.parseArray(x.getRoleIds()), Long.class);
                x.setRoleIdList(ids);
                if (CollectionUtils.isNotEmpty(ids)) {
                    roleIds.addAll(ids);
                }
            }
        });
        if (CollectionUtils.isEmpty(roleIds)) {
            return;
        }
        List<SysRole> sysRoles = this.commonService.findByAttributeList(SysRole.class, "id", roleIds);
        Map<Long, SysRole> roleMap = sysRoles.stream().collect(Collectors.toMap(x -> x.getId(), x -> x, (k1, k2) -> k1));
        records.forEach(x -> {
            if (CollectionUtils.isNotEmpty(x.getRoleIdList())) {
                List<SysRole> rr = new ArrayList<>(x.getRoleIdList().size());
                x.getRoleIdList().forEach(y -> {
                    SysRole r = roleMap.get(y);
                    if (null != r) {
                        rr.add(r);
                    }
                });
                x.setSysRoles(rr);
            }
        });
    }

    @SysLog(description = "保存用户")
    @PostMapping({"/save"})
    public ResultMessage save(@RequestBody UserAddParam param) {
        SysUser user = new SysUser();
        BeanUtils.copyProperties(param, user);
        if (CollectionUtils.isNotEmpty(param.getRoleIdList())) {
            user.setRoleIds(JSONUtil.toJsonStr(param.getRoleIdList()));
        } else {
            user.setRoleIds("[]");
        }
        if (null == user.getId()) {
            checkUserInfo4Add(user);
            EncryptTool tool = new EncryptTool(user.getUsername());
            String password = tool.encrypt(param.getPassword());
            user.setPassword(password);
            user.setRegDate(DateUtils.getCurrDate(null));
            this.commonService.commonAdd(user);
        } else {
            user.setPassword(null);
            user.setUsername(null);
            this.commonService.commonSaveOrUpdate(user, user.getId());
        }
        return ResultMessage.success();
    }

    private void checkUserInfo4Add(SysUser u) {
        if (StringUtils.isBlank(u.getUsername()) || StringUtils.isBlank(u.getPassword())) {
            throw new CommonPartsExceptions("参数异常");
        }
        SysUser oldU = commonService.findOneByAttribute(SysUser.class, "username", u.getUsername());
        if (null != oldU) {
            throw new CommonPartsExceptions("改用户名已经存在");
        }
    }


    @SysLog(description = "删除用户")
    @DeleteMapping({"/delete"})
    public ResultMessage delete(Long id) {
        if (null == id) {
            throw new CommonPartsExceptions("参数异常");
        }
        commonService.commonDelete(SysUser.class, id);
        return ResultMessage.success();
    }
}
